package org.sean.framework.canary.loadbalancer.predicate;

import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import org.sean.framework.canary.loadbalancer.PredicateKey;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.http.HttpHeaders;

import javax.annotation.Nullable;
import java.util.List;

public abstract class AbstractServerPredicate implements Predicate<PredicateKey> {

    public static AbstractServerPredicate alwaysTrue() {
        return new AbstractServerPredicate() {
            @Override
            public boolean apply(@Nullable PredicateKey input) {
                return true;
            }
        };
    }

    public AbstractServerPredicate() {
    }

    /**
     * Get servers filtered by this predicate from list of servers.
     *
     * @param servers 实例列表
     * @param headers 请求头
     * @return 可选实例
     */
    public List<ServiceInstance> getEligibleServers(List<ServiceInstance> servers, HttpHeaders headers) {
        List<ServiceInstance> results = Lists.newArrayList();
        for (ServiceInstance server : servers) {
            if (this.apply(new PredicateKey(server, headers))) {
                results.add(server);
            }
        }
        return results;
    }

    /**
     * Create an instance from a predicate.
     *
     * @param p 条件
     * @return AbstractServerPredicate
     */
    public static AbstractServerPredicate ofKeyPredicate(final Predicate<PredicateKey> p) {
        return new AbstractServerPredicate() {
            @Override
            public boolean apply(PredicateKey input) {
                return p.apply(input);
            }
        };
    }
}
